package org.opu.db.obj.vis;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.UIManager;
import org.mockito.Mockito;
import org.opu.db.obj.vis.domain.AttributeService;
import org.opu.db.obj.vis.domain.AttributeServiceImpl;
import org.opu.db.obj.vis.domain.ObjectService;
import org.opu.db.obj.vis.domain.ObjectServiceImpl;
import org.opu.db.obj.vis.domain.dao.ObjectEntryDao;
import org.opu.db.obj.vis.domain.dao.impl.AttributeDaoImpl;
import org.opu.db.obj.vis.domain.dao.impl.ObjectEntryDaoImpl;
import org.opu.db.obj.vis.domain.dao.impl.StorageFactory;
import org.opu.db.obj.vis.domain.dao.impl.StorageFactoryImpl;
import org.opu.db.obj.vis.domain.wrappers.MappingHelper;
import org.opu.db.obj.vis.ui.actions.About;
import org.opu.db.obj.vis.ui.actions.AbstractAction;
import org.opu.db.obj.vis.ui.actions.AttributesList;
import org.opu.db.obj.vis.ui.actions.Delete;
import org.opu.db.obj.vis.ui.actions.Details;
import org.opu.db.obj.vis.ui.actions.Exit;
import org.opu.db.obj.vis.ui.actions.NewDatabase;
import org.opu.db.obj.vis.ui.actions.ObjectsList;
import org.opu.db.obj.vis.ui.actions.Process;
import org.opu.db.obj.vis.ui.client.MainView;
import org.opu.db.obj.vis.ui.client.MainViewImpl;
import org.opu.db.obj.vis.ui.client.beanviews.TabelBeanView;
import org.opu.db.obj.vis.ui.client.tablerenders.TableRender;
import org.opu.db.obj.vis.ui.client.tablerenders.TableRenderAttribute;
import org.opu.db.obj.vis.ui.client.tablerenders.TableRenderNull;
import org.opu.db.obj.vis.ui.client.tablerenders.TableRenderObject;
import org.opu.db.obj.vis.ui.util.ConfigPath;
import org.opu.db_vdumper.beans.ApplicationData;

public class App {

    public static void main(String[] args) {
    	try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
		}

        StorageFactory storageFactory = getStorageFactory();
        ObjectEntryDao objectDao = getObjectDao(storageFactory);
        ObjectService objectService = getObjectService(objectDao);
        AttributeService attributeService = getAttributeService(objectDao);
        MainView view = getMainView();
        ApplicationData applicationData = getApplicationData(view);
        List actions = getActions(objectService, attributeService, view, applicationData);

        List availableActions = new ArrayList(actions);

        view.initActions(availableActions);
        view.fireState();
        view.asFrame().setVisible(true);
    }

    private static List getActions(ObjectService objectService, 
            AttributeService attributeService, MainView view,
            ApplicationData applicationData ) {

        List list = new ArrayList();
        
        addActionToList(new About(), list, view);
        
        addActionToList(new AttributesList(), list, view)
                .setObjectService(objectService);
        
        addActionToList(new Details(), list, view)
                .setObjectService(objectService);

        addActionToList(new Exit(), list, view);

        ObjectsList objectsList = addActionToList(new ObjectsList(), list, view);
        objectsList.setPublisherService(objectService);

        NewDatabase newDatabase = addActionToList(new NewDatabase(), list, view);
        newDatabase.setApplicationData(applicationData);
        newDatabase.setObjectsListAction(objectsList);
        newDatabase.setObjectService(objectService);
        
        addActionToList(new Process(), list, view);

        Delete delete = addActionToList(new Delete(), list, view);
        delete.setObjectService(objectService);
        delete.setAttributeService(attributeService);

        return list;
    }

    private static <A extends AbstractAction> A addActionToList(A action,
            List list, MainView view) {
        action.setMainView(view);
        list.add(action);
        return action;
    }

    private static MainView getMainView() {
        return new MainViewImpl(new TabelBeanView(), Arrays
                    .<TableRender<?>>asList(
                new TableRenderNull(),
                new TableRenderAttribute(),
                new TableRenderObject()));
    }

    private static ObjectEntryDao getObjectDao(StorageFactory storageFactory) {
        return new ObjectEntryDaoImpl(storageFactory);
    }

    private static ObjectService getObjectService(ObjectEntryDao objectDao) {
        return new ObjectServiceImpl(objectDao,new MappingHelper());
    }

    private static AttributeService getAttributeService(ObjectEntryDao objectDao) {
        return new AttributeServiceImpl(new AttributeDaoImpl(objectDao));
    }

    private static StorageFactory getStorageFactory() {
        ConfigPath cp = ConfigPath.getInstance();
        String name = cp.getConnectionProp().getName();

        StorageFactoryImpl storageFactoryImpl = new StorageFactoryImpl(name);
        storageFactoryImpl.setDirectory(cp.getApplicationConfDir());

        return storageFactoryImpl;
    }

    private static ApplicationData getApplicationData(MainView mainView) {
        return new ApplicationData(Mockito.mock(org.opu.db_vdumper.ui.MainView.class));
    }
}
